package com.tengju.payment.application.transfer;

import com.tengju.payment.application.channel.ChannelRouteService;
import com.tengju.payment.application.shard.ApplicationException;
import com.tengju.payment.application.shard.ApplicationExceptionCode;
import com.tengju.payment.domain.model.BusinessType;
import com.tengju.payment.domain.model.TradeStatus;
import com.tengju.payment.domain.model.channel.Channel;
import com.tengju.payment.domain.model.channel.ChannelRepository;
import com.tengju.payment.domain.model.transfer.*;
import com.tengju.payment.domain.service.transfer.AbstractTransferService;
import com.tengju.payment.domain.service.transfer.TransferStrategyChooser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 渠道转账服务  包括渠道路由  交互等逻辑
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class TransferService {

    private final TransferStrategyChooser transferStrategyChooser;
    private final TransferRecordRepository transferRecordRepository;
    private final ChannelRouteService channelRouteService;
    private final ChannelRepository channelRepository;
//    private final ServiceLetaxWithdrawLogServiceImpl serviceLetaxWithdrawLogService;

    /**
     * 查询转账记录
     */
    public Transfer findTransfer(BusinessNo businessNo) {
        Transfer transfer = transferRecordRepository.findByBusinessNo(businessNo);
        if (transfer == null) {
            throw ApplicationException.error(ApplicationExceptionCode.TRANSFER_NOT_EXIST, businessNo);
        }
        return transfer;
    }

    public UnionTransferResponse unionStoreTransfer(UnionTransferRequest unionTransferRequest) {
        try {
            //构造转账模型
            TransferForm transferForm = TransferFactory.createTransferForm(unionTransferRequest);

            transferRecordRepository.storeTransfer(transferForm);
            return new UnionTransferResponse(unionTransferRequest.getBusinessNo(),
                    true, TradeStatus.PROCESS, "", "");
        } catch (Exception e) {
            log.error("转账记录登记失败", e);
            throw ApplicationException.error(ApplicationExceptionCode.UNION_TRANSFER_ERROR);
        }
    }

    /**
     * 商户余额查询
     */
    public UnionMerchantBalanceQueryResponse merchantBalanceQuery(UnionMerchantBalanceQueryRequest request) {
        //查询对应渠道
        Channel channel = channelRouteService.channelRouting(BusinessType.DEP_TRANSFER, request.getCertificationType());

        if (channel == null) {
            throw ApplicationException.error(ApplicationExceptionCode.CHANNEL_NOT_FOUND);
        }

        AbstractTransferService abstractTransferService = transferStrategyChooser.chooseTransferStrategy(channel.getChannelType());

        return abstractTransferService.merchantBalanceQuery(channel.getChannelInfo());
    }

    /**
     * 处理中转账结果查询处理
     */
    @Transactional(rollbackFor = Throwable.class)
    public void processTransferHandle(Transfer transfer) {

        //路由规则
        AbstractTransferService abstractTransferService = transferStrategyChooser.chooseTransferStrategy(transfer.getChannelType());

        Channel channel = channelRepository.findByChannelId(transfer.getChannelId());

        UnionTransferQueryResponse unionTransferQueryResponse = abstractTransferService.transferQuery(transfer, channel.getChannelInfo());

        if (unionTransferQueryResponse.getTradeStatus() == transfer.getTradeStatus()) {
            return;
        }

        //更新转账后状态
        transfer.handleChannelResponse(unionTransferQueryResponse.getTradeStatus(),
                unionTransferQueryResponse.getCompleteTime(), unionTransferQueryResponse.getChannelRespMessage());

        //更新记录
        transferRecordRepository.updateTransfer(TradeStatus.PROCESS, transfer);
    }


    /**
     * 转账提交
     */
    @Transactional(rollbackFor = Throwable.class)
    public void transferSubmit(Transfer transfer) {
        if (TradeStatus.CREATED != transfer.getTradeStatus()) {
            throw ApplicationException.error(ApplicationExceptionCode.TRADE_STATUS_ERROR, transfer.getBusinessType().name(), transfer.getTransferId(), transfer.getTradeStatus().name());
        }

        //查询对应渠道
        Channel channel = channelRouteService.channelRouting(BusinessType.DEP_TRANSFER, transfer.getExtra().getCertificationType());
        if (channel == null) {
            throw ApplicationException.error(ApplicationExceptionCode.CHANNEL_NOT_FOUND);
        }

        //转账记录发起
        transfer.submitChannel(channel);

        //实现策略
        AbstractTransferService abstractTransferService = transferStrategyChooser.chooseTransferStrategy(channel.getChannelType());

        //优先进行查询策略补偿
        UnionTransferQueryResponse unionTransferQueryResponse = abstractTransferService.transferQuery(transfer, channel.getChannelInfo());

        if (unionTransferQueryResponse != null && unionTransferQueryResponse.getTradeStatus() != null) {
            //更新转账后状态
            transfer.handleChannelResponse(unionTransferQueryResponse.getTradeStatus(), unionTransferQueryResponse.getCompleteTime(), unionTransferQueryResponse.getChannelRespMessage());
        } else {
            UnionTransferSubmitResponse unionTransferSubmitResponse = abstractTransferService.transfer(transfer, channel.getChannelInfo());
            //更新转账后状态
            transfer.handleChannelResponse(unionTransferSubmitResponse.getTradeStatus(), unionTransferSubmitResponse.getCompleteTime(), unionTransferSubmitResponse.getChannelRespMessage());
        }
        //更新记录
        transferRecordRepository.updateTransfer(TradeStatus.CREATED, transfer);
    }

}